package proyectoFC_2_3_3.koyicabuto;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.ksoap2.SoapEnvelope;
import org.ksoap2.SoapFault;
import org.ksoap2.serialization.PropertyInfo;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapPrimitive;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import org.xmlpull.v1.XmlPullParserException;

import proyectoFC_2_3_3.koyicabuto.BaseDeDatos.GruposDataBase;
import proyectoFC_2_3_3.koyicabuto.balloonOverlay.BalloonItemizedOverlay;
import proyectoFC_2_3_3.koyicabuto.custom_menu.CustomMenu;
import proyectoFC_2_3_3.koyicabuto.custom_menu.CustomMenu.OnMenuItemSelectedListener;
import proyectoFC_2_3_3.koyicabuto.custom_menu.CustomMenuItem;
import proyectoFC_2_3_3.koyicabuto.funciones.FuncionesBaseDatos;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.view.KeyEvent;
import android.view.View;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;


public class TabMapsGrupoActivity extends MapActivity  implements OnMenuItemSelectedListener{
 
    private MapView mapa = null;
    private MapController mapController = null;
    private Long idGrupoSeleccionado = null;
    private  MyItemizedOverlay myItemizedOverlay = null;
    
    private CustomMenu mMenu;
	public static final int MENU_SATELITE = 1;
	public static final int MENU_TRAFICO = 2;
	public static final int MENU_ZOOM_IN = 3;
	public static final int MENU_ZOOM_OUT = 4;
	
	private static final String BANDERA_EVENTO = "EVENTO";
	private static final String BANDERA_CONTACTO = "CONTACTO";
	private static final String BANDERA_USUARIO = "USUARIO";
    
	private FuncionesBaseDatos funcionesBaseDeDatos = new FuncionesBaseDatos();
    
	/**
	 * listaEventos[0] = id
	 * listaEventos[1] = EV_NOMBRE
	 * listaEventos[2] = EV_LONGITUD
	 * listaEventos[3] = EV_LATITUD
	 */
    private List<Object[]> listaEventos = new ArrayList<Object[]>();
	
    /**
     * array[0] = Nombre
     * array[1] = Contact_Id
     * array[2] = Numero
     */
    private List<String[]> listaPersonasGrupos = new ArrayList<String[]>(); 
    
    private static final String NAMESPACE = "http://hellowebservice";
	private static String URL="http://10.0.2.2:8080/HelloWebService/services/HelloWSImpl?WSDL"; 
	private static final String METHOD_NAME = "hello";
	private static final String SOAP_ACTION =  "http://hellowebservice/hello";
	
	private Double longitud = null;
	private String nombreUsuario = null;
	private Double latitud = null;
	
	private boolean showEventos = false;
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.tabmapsgrupo);
        
        //Obtenemos las ultimas coordenadas que tenga el usuario en la BB.DD para que al mostrar el mapa, aparezca centrado sobre 
        //su ultima posicion conocida, hasta que se actualice su posicion de nuevo.
        Object[] datosUsuario = obtenerDatosUsuario();
        
        latitud = (Double)datosUsuario[0];
		longitud = (Double)datosUsuario[1];
		nombreUsuario = (String)datosUsuario[2];
        
        //Obtenemos una referencia al control MapView
        mapa = (MapView)findViewById(R.id.mapa);
        
        //Obtenemos las variables que vienen de GruposListViewActivity
  		Bundle extras = getIntent().getExtras();
  		if(extras != null){
  			idGrupoSeleccionado = extras.getLong("idGrupoSeleccionado");
  		}
        
        //Obtenemos el controlador del mapa
        mapController = mapa.getController();
        
        //TODO:hacer que las coordenadas las coja de la base de datos en vez de preguntar al WebService
        //Centramos el mapa en el punto cuyas coordenadas obtenemos anteriormente del WebService
        GeoPoint loc = new GeoPoint(latitud.intValue(), longitud.intValue());
        mapController.setCenter(loc);
        mapController.setZoom(10);
        
        //Mostramos los controles de zoom sobre el mapa
        mapa.setSatellite(false);
        
            
	      //Cargamos las personas del grupo seleccionado y las cargamos en listaPersonasGrupos
	      cargaPersonas();
	      
	      //Obtenemos los Overlays del Map
	      List<Overlay> mapOverlays = mapa.getOverlays();
	      
	      Drawable drawable = null;
	      
	      if(showEventos){
	    	  drawable = this.getResources().getDrawable(R.drawable.target_map_selector);
	    	  myItemizedOverlay = new MyItemizedOverlay(drawable, mapa, BANDERA_EVENTO);
    	  }else{
    		  drawable = this.getResources().getDrawable(R.drawable.marker_map_selector);
    		  myItemizedOverlay = new MyItemizedOverlay(drawable, mapa, BANDERA_CONTACTO);
    	  }
	      
	      String selectGrupo = null;
	      String[] parametros = null;
	      
	      //Obtenemos de la listaPersonasGrupos las coordenadas de sus posiciones para mostrarlos en el Map, es decir,
	      //creamos un Overlay por cada persona del Grupo para poder mostrar informacion sobre la misma en el Map
	      for(int i = 0; i<listaPersonasGrupos.size(); i++){
	    	  
    		  //Estamos en el caso de que es un contacto de la agenda del terminal
    		  selectGrupo = "SELECT PG_LONGITUD, PG_LATITUD FROM PERSONAL_GRUPOS WHERE PG_PER_ID = ? AND PG_USUARIO = 0 ";
    		  parametros = new String[]{listaPersonasGrupos.get(i)[1].toString()};
	    	  
	    	  GruposDataBase  gruposDataBaseHelper = new GruposDataBase(this, "GruposDataBase", null, 1);
			  SQLiteDatabase gruposDataBase = gruposDataBaseHelper.getReadableDatabase();	
			  
			  Double latitud = null;
	    	  Double longitud = null;
			  
			  try{
				  if(gruposDataBase != null){
					  Cursor cursor = gruposDataBase.rawQuery(selectGrupo, parametros);
					  
					  
					  if(cursor.moveToFirst()){
						  do{
							  longitud = cursor.getDouble(0)*1E6;
							  latitud = cursor.getDouble(1)*1E6;
						  }while(cursor.moveToNext());
						}
				  }			
				  gruposDataBase.close();
				
			  }catch (Exception e) {
				  System.out.println("Excepcion en TabsMapsGrupoActivity: " + e.getMessage());
			  }
			  
		      GeoPoint point = new GeoPoint(latitud.intValue(),longitud.intValue());
		      OverlayItem overlayitem = new OverlayItem(point, listaPersonasGrupos.get(i)[0], listaPersonasGrupos.get(i)[1]);
		      
		      myItemizedOverlay.addOverlay(overlayitem);
		      mapOverlays.add(myItemizedOverlay);
	      }	      
	      
	      //TODO:eliminar que aparezca un item para el usuario, solo q aparezca el mapa centrado en su posicion
	      //Ahora creamos un Overlay para el Usuario
	      GeoPoint pointUsuario = new GeoPoint(latitud.intValue(),longitud.intValue());
	      OverlayItem overlayitemUsuario = new OverlayItem(pointUsuario, nombreUsuario, null);
	      
	      Drawable drawableUsuario = this.getResources().getDrawable(R.drawable.marker_map_selector_user);
	      MyItemizedOverlay myItemizedOverlayUsuario = new MyItemizedOverlay(drawableUsuario, mapa, BANDERA_USUARIO);
	      
	      myItemizedOverlayUsuario.addOverlay(overlayitemUsuario);
	      mapOverlays.add(myItemizedOverlayUsuario);
	      
	    //initialize the menu
	    mMenu = new CustomMenu(this, this, getLayoutInflater());
	    mMenu.setHideOnSelect(false);
	    mMenu.setItemsPerLineInPortraitOrientation(4);
	    mMenu.setItemsPerLineInLandscapeOrientation(8);
	    //load the menu items
	    loadMenuItems();
    }
    
    /**
     * Snarf the menu key.
     */
	public boolean onKeyDown(int keyCode, KeyEvent event) { 
	    if (keyCode == KeyEvent.KEYCODE_MENU) {
	    	doMenu();
	    	return true;
	    }
		return super.onKeyDown(keyCode, event); 
	} 
	
	/**
     * Load up our menu.
     */
	private void loadMenuItems() {
		//This is kind of a tedious way to load up the menu items.
		//Am sure there is room for improvement.
		ArrayList<CustomMenuItem> menuItems = new ArrayList<CustomMenuItem>();
		CustomMenuItem cmi = new CustomMenuItem();
		cmi.setCaption("Satélite");
		cmi.setImageResourceId(R.drawable.ic_menu_view_72);
		cmi.setId(MENU_SATELITE);
		menuItems.add(cmi);
		cmi = new CustomMenuItem();
		cmi.setCaption("Tráfico");
		cmi.setImageResourceId(R.drawable.ic_menu_traffic_lights);
		cmi.setId(MENU_TRAFICO);
		menuItems.add(cmi);
		cmi = new CustomMenuItem();
		cmi.setCaption("Zoom");
		cmi.setImageResourceId(R.drawable.ic_menu_zoom_plus_72);
		cmi.setId(MENU_ZOOM_IN);
		menuItems.add(cmi);
		cmi = new CustomMenuItem();
		cmi.setCaption("Zoom");
		cmi.setImageResourceId(R.drawable.ic_menu_zoom_out_72);
		cmi.setId(MENU_ZOOM_OUT);
		menuItems.add(cmi);
		if (!mMenu.isShowing())
		try {
			mMenu.setMenuItems(menuItems);
		} catch (Exception e) {

		}
	}
	
	/**
     * Toggle our menu on user pressing the menu key.
     */
	private void doMenu() {
		if (mMenu.isShowing()) {
			mMenu.hide();
		} else {
			//Note it doesn't matter what widget you send the menu as long as it gets view.
			mMenu.show(findViewById(R.id.mapa));
		}
	}
 
    @Override
    protected boolean isRouteDisplayed() {
        return false;
    }
    
    //TODO:hacer que las coordenadas las coja de la base de datos en vez de preguntar al WebService
    /**
     * Metodo con el que realizamos una conexion con el WebService, le pasamos unas coordenadas y las obtenemos llamando a 
     * un metodo del WebService que nos las devuelve.
     * Estas coordenadas las usamos para obtener unas coordenadas donde centrar la pantalla al iniciar el Activity.
     * @return
     */
    public String conectaWebService(){
    	
    	String result = null;
    	
    	SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
        
        PropertyInfo propInfo=new PropertyInfo();
        propInfo.name="arg0";
        propInfo.type=PropertyInfo.STRING_CLASS;
        Double lat = 37.4006248380574*1E6;
        Double longi = -5.937037467956543*1E6;
        propInfo.setValue(lat.toString() + "@" + longi.toString());
        request.addProperty(propInfo);
        
        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); 
        envelope.setOutputSoapObject(request);
        
        HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
        try {
			androidHttpTransport.call(SOAP_ACTION, envelope);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (XmlPullParserException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        
        
        SoapPrimitive resultsRequestSOAP = null;
		try {
			resultsRequestSOAP = (SoapPrimitive) envelope.getResponse();
		} catch (SoapFault e) {
			e.printStackTrace();
		}
		if(resultsRequestSOAP != null){
			result = resultsRequestSOAP.toString();
		}
       
        return result;
    }
    
    /**
     * Metodo con el que obtenemos una lista<String[]> con los datos de las personas del grupoSeleccionado. Los 
     * datos loa obtenemos consultando en la BB.DD de la aplicacion.
     */
    private void cargaPersonas(){
		listaPersonasGrupos = new ArrayList<String[]>();
		
		String cadenaId = cargaPersonalGrupo(idGrupoSeleccionado);
		
		if(cadenaId != null){
		    
			Cursor mCursor = getContentResolver().query(
					  Data.CONTENT_URI, new String[] { Data._ID, Data.DISPLAY_NAME, Phone.NUMBER, Data.CONTACT_ID},
					  Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE + "' AND " + Phone.NUMBER + " IS NOT NULL " + 
					  "AND " + Data.CONTACT_ID + " in " + cadenaId , null, Data.DISPLAY_NAME + " ASC ");
			
			if(mCursor.moveToFirst()){
				do{
					String[] array =  new String[3];
					array[0] = mCursor.getString(1); 
					array[1] = mCursor.getString(3);
					array[2] = mCursor.getString(2);
					
					listaPersonasGrupos.add(array);
				}while(mCursor.moveToNext());
			}
		}
    }
    
    /**
     * Cuando picamos en una opcion del menu principal
     */
	public void MenuItemSelectedEvent(CustomMenuItem selection) {
		int selectionID = selection.getId();
		if(selectionID == TabMapsGrupoActivity.MENU_SATELITE){
			mostrarSatelite();
		}else if(selectionID == TabMapsGrupoActivity.MENU_TRAFICO){
			mostrarTrafico();
		}else if(selectionID == TabMapsGrupoActivity.MENU_ZOOM_IN){
			mapController.zoomIn();
		}else if(selectionID == TabMapsGrupoActivity.MENU_ZOOM_OUT){
			mapController.zoomOut();
		}
	}
	
	public void mostrarTrafico(){
		if(mapa.isTraffic()){
    		mapa.setTraffic(false);
    	}else{
    		mapa.setTraffic(true);
    	}
	}
	
	public void mostrarSatelite(){
		if(mapa.isSatellite())
            mapa.setSatellite(false);
        else
            mapa.setSatellite(true);
	}
	
	/**
	 * Metodo con el que obtenemos las coordenadas del usuario en la BB.DD.
	 * @return
	 */
	private Object[] obtenerDatosUsuario(){
		Object[] datos = new Object[3];
		
		SQLiteDatabase gruposDataBase = funcionesBaseDeDatos.conectaBaseDeDatos(this);
		String selectCoordenadas = "SELECT USU_LATITUD, USU_LONGITUD, USU_NOMBRE FROM USUARIO ";
		
		try{
			if(gruposDataBase != null){
				Cursor cursor = gruposDataBase.rawQuery(selectCoordenadas, null);
				if(cursor.moveToFirst()){
					do{
						datos[0] = cursor.getDouble(0)*1E6;
						datos[1] = cursor.getDouble(1)*1E6;
						datos[2] = cursor.getString(2);
					}while(cursor.moveToNext());
				}
				funcionesBaseDeDatos.cierraBaseDeDatos(gruposDataBase);
			}
			
		}catch (Exception e) {
			System.out.println("Excepcion al obtener coordenadas: " +e.getMessage());
		}
		
		return datos;
	}
	
	public void onClickBotonVolver(View view){
		Intent i = new Intent(this, ListaGruposActivity.class);
		startActivity(i);
	}
	
	public void onClickBotonEventos(View view){
		
		List<Overlay> mapOverlays = mapa.getOverlays();
		
		for (Overlay overlay : mapOverlays) {
			if (overlay instanceof BalloonItemizedOverlay) {
				((BalloonItemizedOverlay) overlay).hideBalloon();
			}
		}
		
		//Eliminamos los overlays 
		myItemizedOverlay.clearOverlay();
	    mapa.getOverlays().clear();
	    
	    mapOverlays.clear();
	    mapOverlays = mapa.getOverlays();	    
		
		if(!showEventos){
		    //Añadimos los overlays de los eventos
		    cargaEventos();
		    
			Drawable drawable = this.getResources().getDrawable(R.drawable.target_map_selector);
			myItemizedOverlay = new MyItemizedOverlay(drawable, mapa, BANDERA_EVENTO);
		  
		    
		    //Obtenemos de la listaPersonasGrupos las coordenadas de sus posiciones para mostrarlos en el Map, es decir,
		    //creamos un Overlay por cada persona del Grupo para poder mostrar informacion sobre la misma en el Map
		    for(int i = 0; i<listaEventos.size(); i++){
			  
			    longitud = (Double)listaEventos.get(i)[2]*1E6;
			    latitud =  (Double)listaEventos.get(i)[3]*1E6;
			  
		        GeoPoint point = new GeoPoint(latitud.intValue(),longitud.intValue());
		        OverlayItem overlayitem = new OverlayItem(point, listaEventos.get(i)[1].toString(), listaEventos.get(i)[0].toString());
		      
		        myItemizedOverlay.addOverlay(overlayitem);
		        mapOverlays.add(myItemizedOverlay);
		        
		        showEventos = true;
		    }
		}else{
			//Cargamos las personas del grupo seleccionado y las cargamos en listaPersonasGrupos
		    cargaPersonas();
		    
		    String selectGrupo = null;
		      String[] parametros = null;
		      
		      //Obtenemos de la listaPersonasGrupos las coordenadas de sus posiciones para mostrarlos en el Map, es decir,
		      //creamos un Overlay por cada persona del Grupo para poder mostrar informacion sobre la misma en el Map
		      for(int i = 0; i<listaPersonasGrupos.size(); i++){
		    	  
	    		  //Estamos en el caso de que es un contacto de la agenda del terminal
	    		  selectGrupo = "SELECT PG_LONGITUD, PG_LATITUD FROM PERSONAL_GRUPOS WHERE PG_PER_ID = ? AND PG_USUARIO = 0 ";
	    		  parametros = new String[]{listaPersonasGrupos.get(i)[1].toString()};
		    	  
		    	  GruposDataBase  gruposDataBaseHelper = new GruposDataBase(this, "GruposDataBase", null, 1);
				  SQLiteDatabase gruposDataBase = gruposDataBaseHelper.getReadableDatabase();	
				  
				  Double latitud = null;
		    	  Double longitud = null;
				  
				  try{
					  if(gruposDataBase != null){
						  Cursor cursor = gruposDataBase.rawQuery(selectGrupo, parametros);
						  
						  
						  if(cursor.moveToFirst()){
							  do{
								  longitud = cursor.getDouble(0)*1E6;
								  latitud = cursor.getDouble(1)*1E6;
							  }while(cursor.moveToNext());
						  }
						  gruposDataBase.close();
					  }			
					
				  }catch (Exception e) {
					  System.out.println("Excepcion en TabsMapsGrupoActivity: " + e.getMessage());
				  }
				  
				  if(latitud != null && longitud != null){
					  
				      GeoPoint point = new GeoPoint(latitud.intValue(),longitud.intValue());
				      OverlayItem overlayitem = new OverlayItem(point, listaPersonasGrupos.get(i)[0], listaPersonasGrupos.get(i)[1]);
				      
				      Drawable drawable = this.getResources().getDrawable(R.drawable.marker_map_selector);
					  myItemizedOverlay = new MyItemizedOverlay(drawable, mapa, BANDERA_CONTACTO);
				      myItemizedOverlay.addOverlay(overlayitem);
				      mapOverlays.add(myItemizedOverlay);
				  }
		      }	      
		      
		      Object[] datosUsuario = obtenerDatosUsuario();
		         
	          latitud = (Double)datosUsuario[0];
			  longitud = (Double)datosUsuario[1];
			  nombreUsuario = (String)datosUsuario[2];
		      //Ahora creamos un Overlay para el Usuario
		      GeoPoint pointUsuario = new GeoPoint(latitud.intValue(),longitud.intValue());
		      OverlayItem overlayitemUsuario = new OverlayItem(pointUsuario, nombreUsuario, null);
		      
		      Drawable drawableUsuario = this.getResources().getDrawable(R.drawable.marker_map_selector_user);
		      MyItemizedOverlay myItemizedOverlayUsuario = new MyItemizedOverlay(drawableUsuario, mapa, BANDERA_USUARIO);
		      
		      myItemizedOverlayUsuario.addOverlay(overlayitemUsuario);
		      mapOverlays.add(myItemizedOverlayUsuario);
		      
		      showEventos = false;
		}
		mapa.invalidate();
	}
	
	private void cargaEventos(){
		listaEventos = new ArrayList<Object[]>();
			
		//Obtenemos los eventos
		String selectEventos = "SELECT _id, EV_NOMBRE, EV_LONGITUD, EV_LATITUD FROM EVENTOS WHERE EV_GR_ID = ? ";
		String[] parametros = new String[]{idGrupoSeleccionado.toString()};
		
		SQLiteDatabase gruposDataBase = funcionesBaseDeDatos.conectaBaseDeDatos(this);	
		
		try{
			if(gruposDataBase != null){
				Cursor cursor = gruposDataBase.rawQuery(selectEventos, parametros);
	
				if(cursor.moveToFirst()){
					do{
						Object[] array =  new Object[4];
						array[0] = cursor.getInt(0);
						array[1] = cursor.getString(1);
						array[2] = cursor.getDouble(2);
						array[3] = cursor.getDouble(3);
						
						listaEventos.add(array);
					}while(cursor.moveToNext());
				}
				funcionesBaseDeDatos.cierraBaseDeDatos(gruposDataBase);
			}					
		}catch (Exception e) {
			System.out.println("Excepcion en cargaEventos: " + e.getMessage());
		}
    }
			
	
	@Override
	public void onPause(){
		if(mMenu.isShowing()){
			mMenu.hide();
		}
		super.onPause();
	}
	
	private String cargaPersonalGrupo(Long idGrupo){
		List<Long> listaId = new ArrayList<Long>();
		String cadena = null;
		String[] parametros = new String[]{idGrupo.toString()};
		String selectGrupo = "SELECT PG_PER_ID FROM PERSONAL_GRUPOS WHERE PG_GR_ID = ? ";
		
		GruposDataBase  gruposDataBaseHelper = new GruposDataBase(this, "GruposDataBase", null, 1);
		SQLiteDatabase gruposDataBase = gruposDataBaseHelper.getReadableDatabase();	
		
		try{
			if(gruposDataBase != null){
				Cursor cursor = gruposDataBase.rawQuery(selectGrupo, parametros);
	
				if(cursor.moveToFirst()){
					do{
						listaId.add(cursor.getLong(0));
					}while(cursor.moveToNext());
				}
				gruposDataBase.close();
			}			
		
		}catch (Exception e) {
			System.out.println("Excepcion en cargaPersonalGrupo: " +e.getMessage());
		}
		
		if(listaId != null && !listaId.isEmpty()){
			cadena = "(";
			for(Long iteracion:listaId){
				cadena = cadena + iteracion + ",";
			}
			cadena = cadena.substring(0, cadena.length() - 1);
			cadena = cadena + ")";
		}
		
		return cadena;
	}
}